package com.kingbook.core.base;

import com.alibaba.fastjson.JSONObject;
import com.kingbook.core.cache.CacheConfig;
import com.kingbook.core.exception.DatabaseAccessException;
import com.kingbook.core.executor.DatabaseOperations;
import com.kingbook.core.result.JSONPageResult;
import com.kingbook.core.result.JSONResult;
import com.kingbook.core.sql.SqlContext;
import com.kingbook.core.sql.SqlFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * @Author: Bucky
 * @Date: 2019/1/2
 * @Version 1.0
 */
@Service
public class SQLExecutorService {

    private static Logger logger = LoggerFactory.getLogger(SQLExecutorService.class);

    @Resource
    private DatabaseOperations operations;

    private String pageNo = "pageNo";

    private String pageSize = "pageSize";

    private static String errMsg = "数据库处理异常";


    /**
     * 返回第一条结果
     *
     * @param sql
     * @return
     */
    public Map findFirstMap(String sql, CacheConfig cacheConfig) {
        return findFirst(sql, Map.class, cacheConfig);
    }

    /**
     * 返回第一条结果
     *
     * @param sql
     * @return
     */
    public JSONObject findFirstJson(String sql, CacheConfig cacheConfig) {
        return findFirst(sql, JSONObject.class, cacheConfig);
    }

    /**
     * 返回第一条结果
     *
     * @param sql
     * @return
     */
    public <T> T findFirst(String sql, Class<T> clazz, CacheConfig cacheConfig) {
        try {
            return operations.findFirst(sqlContext(sql, cacheConfig), clazz);
        } catch (DatabaseAccessException e) {
            return null;
        }
    }


    //////////////////////////////////////////////////////////////////////////////

    public Map<String, ?>[] queryMap(String sql, CacheConfig cacheConfig) {
        try {
            return operations.queryMap(sqlContext(sql, cacheConfig));
        } catch (DatabaseAccessException e) {
            return null;
        }
    }

    /**
     * 普通查询
     */
    public JSONResult queryJson(String sql, CacheConfig cacheConfig) {
        try {
            return operations.query(sqlContext(sql, cacheConfig));
        } catch (DatabaseAccessException e) {
            return JSONResult.failed(errMsg);
        }
    }

    /**
     * 返回对象列表
     */
    public <T> List<T> query(String sql, Class<T> clazz, CacheConfig cacheConfig) {
        try {
            return operations.query(sqlContext(sql, cacheConfig), clazz);
        } catch (DatabaseAccessException e) {
            return null;
        }
    }

    //////////////////////////////////////////////////////////////////////////////

    /**
     * 具有分页功能的查询
     */
    public JSONPageResult queryForPages(String sql, String cSql, int pageNo, int pageSize, CacheConfig cacheConfig) {
        try {
            logger.info(sql + "\n" + cSql);
            pageSize = pageSize < 50 ? pageSize : 50;
            return operations.queryForPages(SqlFactory.getSqlPageContext(sql, cSql, pageNo, pageSize, operations.getDBDialect(), cacheConfig), null);
        } catch (DatabaseAccessException e) {
            return JSONPageResult.failed(errMsg);
        }
    }

    public int getRows(String sql, CacheConfig cacheConfig) {
        try {
            return operations.getRows(sqlContext(sql, cacheConfig));
        } catch (DatabaseAccessException e) {
            return 0;
        }
    }

    //////////////////////////////////////////////////////////////////////////////

    public JSONResult insert(String sql) {
        try {
            return operations.update(sqlContext(sql, null));
        } catch (DatabaseAccessException e) {
            return JSONResult.failed(errMsg);
        }
    }

    public JSONResult insertReturnKey(String sql) {
        try {
            return operations.insertReturnKey(sqlContext(sql, null));
        } catch (DatabaseAccessException e) {
            return JSONResult.failed(errMsg);
        }
    }

    //////////////////////////////////////////////////////////////////////////////

    public JSONResult update(String sql) {
        try {
            return operations.update(sqlContext(sql, null));
        } catch (DatabaseAccessException e) {
            return JSONResult.failed(errMsg);
        }
    }

    //////////////////////////////////////////////////////////////////////////////

    public JSONResult delete(String sql) {
        try {
            return operations.update(sqlContext(sql, null));
        } catch (DatabaseAccessException e) {
            return JSONResult.failed(errMsg);
        }
    }

    //////////////////////////////////////////////////////////////////////////////

    public JSONResult batchUpdate(String... sql) {
        try {
            return operations.batchUpdate(sql);
        } catch (DatabaseAccessException e) {
            return JSONResult.failed(errMsg);
        }
    }

    ///////////////////////////////////////////////////////////////////////////

    private SqlContext sqlContext(String sql, CacheConfig cacheConfig) {
        return SqlFactory.getSqlContext(sql, operations.getDBDialect(), cacheConfig);
    }

}
